home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / utilities / bmfc000.lha / BMFC / src / bmfc / bmfc.c next >
Encoding:
C/C++ Source or Header  |  1992-08-31  |  12.4 KB  |  424 lines

  1. /**************************************/
  2. /* bmfc.c                             */
  3. /* for BMFC 0.00                      */
  4. /* Copyright 1992 by Adam M. Costello */
  5. /**************************************/
  6.  
  7.  
  8. #include <limits.h>
  9.  
  10. #if UCHAR_MAX != 255
  11. #error ---------------------------------------
  12. #error Danger!  Danger!  UCHAR_MAX is not 255!
  13. #error ---------------------------------------
  14. #endif
  15.  
  16. #include "build.h"
  17. #include "error.h"
  18. #include <stdlib.h>
  19.  
  20.  
  21. static const char
  22.  
  23.   /* Error messages: */
  24.  
  25.   *const cantopenread  = "Unable to open file \"%s\" for reading.\n",
  26.   *const cantopenwrite = "Unable to open file \"%s\" for writing.\n",
  27.   *const cantwrite     = "Unable to write to file.\n",
  28.  
  29.   /* Warning messages: */
  30.  
  31.   *const cantclose     = "Unable to close file \"%s\".\n",
  32.   *const success       = "Compilation successful.\n",
  33.   *const outputto      = "Output written to \"%s\".\n";
  34.  
  35. static FILE *writefile;  /* Only for use by write...() functions. */
  36.  
  37.  
  38. static void writeubyte(unsigned char b)  /* Writes b to writefile. */
  39. {
  40.   if (putc(b,writefile) == EOF) failf(cantwrite);
  41. }
  42.  
  43.  
  44. static void writeubytes(int n, unsigned char *b)  /* Writes n bytes from */
  45. {                                                 /* *b to writefile.    */
  46.   while (n--) writeubyte(*b++);
  47. }
  48.  
  49.  
  50. static void writeuword(unsigned short w)  /* Write w to writefile, */
  51. {                                         /* high byte first.      */
  52.   writeubyte((w & 0xFF00) >> 8);
  53.   writeubyte(w & 0xFF);
  54. }
  55.  
  56.  
  57. static void writeword(short w)  /* Write w to writefile, high byte first. */
  58. {
  59.   writeuword(w >= 0 ? w : w + 0x10000);
  60. }
  61.  
  62.  
  63. static void writeulong(unsigned short L)  /* Write L to writefile, */
  64. {                                         /* high byte first.      */
  65.   writeubyte((L & 0xFF000000) >> 24);
  66.   writeubyte((L & 0xFF0000) >> 16);
  67.   writeubyte((L & 0xFF00) >> 8);
  68.   writeubyte(L & 0xFF);
  69. }
  70.  
  71.  
  72. #define writeptr(p)  writeulong(p)
  73.  
  74.  
  75. static void writeloadfile(FILE *loadfile, struct font *thefont)
  76. {
  77.   unsigned long  *theparams = thefont->parameters, cf = theparams[colorfont],
  78.                  d = theparams[depth], rp = theparams[revpath], plane, p,
  79.                  pixmapwidth, roundedpmw, fontname, fontdata, fontloc,
  80.                  fontspace, fontkern, fontcolors, colortable, fontend, codeend;
  81.   unsigned short *thewidths = thefont->widths, *A, *B, *C, *offset, *pwidth,
  82.                  *pA, *lastA, *pB, *pC, *poffset, *lastoffset, defA, defB,
  83.                  defC, defoffset, ys = thefont->ysize, modulo, w;
  84.   unsigned char  **theglyphs = thefont->glyphs, **pglyph, **lastglyph,
  85.                  *prow, *lastrow, *pmrow, *ppix, *lastpix, *pmpix, *pixmap,
  86.                  lowchar, highchar, bitmask;
  87.   unsigned int   numglyphs, defchar;
  88.  
  89.   for (pglyph = theglyphs; !*pglyph; ++pglyph);
  90.   lowchar = pglyph - theglyphs;
  91.   for (pglyph = theglyphs + 255; !*pglyph; --pglyph);
  92.   highchar = pglyph - theglyphs;
  93.   defchar = highchar + 1;
  94.   theglyphs[defchar] = theglyphs[256];
  95.   thewidths[defchar] = thewidths[256];
  96.   numglyphs = defchar - lowchar + 1;
  97.  
  98.   A = (unsigned short *) malloc(numglyphs * sizeof (unsigned short));
  99.   B = (unsigned short *) malloc(numglyphs * sizeof (unsigned short));
  100.   C = (unsigned short *) malloc(numglyphs * sizeof (unsigned short));
  101.   offset = (unsigned short *) malloc(numglyphs * sizeof (unsigned short));
  102.  
  103.   if (!A || !B || !C || !offset) failf(outofmem);
  104.  
  105.   /* Figure out offsets and A, B, and C values: */
  106.  
  107.   for (pglyph = theglyphs + lowchar, pwidth = thewidths + lowchar, pA = A,
  108.          pB = B, pC = C, poffset = offset, pixmapwidth = 0,
  109.          lastglyph = theglyphs + defchar;
  110.        pglyph <= lastglyph;
  111.        ++pglyph, ++pwidth, ++pA, ++pB, ++pC, ++poffset) {
  112.     if (*pglyph) {
  113.       if (!*pwidth) *pA = *pB = *pC = 0;
  114.       else {
  115.         *pA = *pC = w = *pwidth;
  116.         for (prow = *pglyph, lastrow = prow + ys * w;
  117.              prow < lastrow;
  118.              prow += w)
  119.           for (ppix = prow, lastpix = prow + w - 1;
  120.                ppix <= lastpix;
  121.                ++ppix)
  122.             if (*ppix) {
  123.               if (ppix - prow < *pA) *pA = ppix - prow;
  124.               if (lastpix - ppix < *pC) *pC = lastpix - ppix;
  125.             }
  126.         if (*pC == w) *pA = 0;
  127.         *pB = w - *pC - *pA;
  128.       }
  129.       *poffset = pixmapwidth;
  130.       pixmapwidth += *pB;
  131.     }
  132.   }
  133.  
  134.   /* Replicate default glyph onto undefined glyphs: */
  135.  
  136.   defoffset = poffset[-1];
  137.   defA = pA[-1];
  138.   defB = pB[-1];
  139.   defC = pC[-1];
  140.  
  141.   for (pglyph = theglyphs + lowchar, poffset = offset, pA = A, pB = B, pC = C,
  142.          lastglyph = theglyphs + highchar;
  143.        pglyph <= lastglyph;
  144.        ++pglyph, ++poffset, ++pA, ++pB, ++pC)
  145.     if (!*pglyph) {
  146.       *poffset = defoffset;
  147.       *pA = defA;
  148.       *pB = defB;
  149.       *pC = defC;
  150.     }
  151.  
  152.   modulo = ((pixmapwidth + 15) / 16) * 2;
  153.   roundedpmw = modulo * 8;
  154.  
  155.   pixmap = (unsigned char *) malloc(ys * roundedpmw * sizeof (unsigned char));
  156.   if (!pixmap) failf(outofmem);
  157.  
  158.   /* Construct pixmap: */
  159.  
  160.   for (pglyph = theglyphs + lowchar, pwidth = thewidths + lowchar, pA = A,
  161.          pB = B, poffset = offset, lastglyph = theglyphs + defchar;
  162.        pglyph <= lastglyph;
  163.        ++pglyph, ++pwidth, ++pA, ++pB, ++poffset)
  164.     if (*pglyph) {
  165.       w = *pwidth;
  166.       for (prow = *pglyph, pmrow = pixmap + *poffset, lastrow = prow + ys * w;
  167.            prow < lastrow;
  168.            prow += w, pmrow += roundedpmw)
  169.         for (ppix = prow + *pA, pmpix = pmrow, lastpix = ppix + *pB;
  170.              ppix < lastpix;
  171.              ++ppix, ++pmpix)
  172.           *pmpix = *ppix;
  173.     }
  174.  
  175.   for (pmrow = pixmap + pixmapwidth, lastrow = pmrow + (ys - 1) * roundedpmw;
  176.        pmrow <= lastrow;
  177.        pmrow += roundedpmw)
  178.     for (pmpix = pmrow, lastpix = pmrow + (roundedpmw - pixmapwidth);
  179.          pmpix < lastpix;
  180.          ++pmpix)
  181.       *pmpix = 0;
  182.  
  183.   fontname = 26;
  184.   fontdata = cf ? 154 : 110;
  185.   fontloc = fontdata + d * ys * modulo;
  186.   fontspace = fontloc + numglyphs * 4;
  187.   fontkern = fontspace + numglyphs * 2;
  188.   fontend = fontkern + numglyphs * 2;
  189.   if (cf) {
  190.     fontcolors = fontend;
  191.     colortable = fontcolors + 8;
  192.     fontend = colortable + thefont->numcolors * 2;
  193.   }
  194.   codeend = ((fontend + 3) / 4) * 4;
  195.  
  196.   /* Write the load file. */
  197.  
  198.   writefile = loadfile;
  199.  
  200.   /* hunk_header: */
  201.  
  202.   writeubytes(20, "\0\0\x03\xF3\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0");
  203.   writeulong((fontend + 3) / 4);
  204.  
  205.   /* hunk_code: */
  206.  
  207.   writeulong(0x3E9);
  208.   writeulong((fontend + 3) / 4);
  209.  
  210.   /* dfh_ReturnCode: */
  211.  
  212.   writeubyte(0x70);
  213.   writeubyte(theparams[returncode]);
  214.   writeuword(0x4E75);
  215.  
  216.   /* dfh_DF: */
  217.  
  218.   writeubytes(10, "\0\0\0\0\0\0\0\0\x0C\0");
  219.   writeptr(fontname);
  220.  
  221.   writeuword(0x0F80);               /* dfh_FileID                 */
  222.   writeuword(theparams[revision]);  /* dfh_Revision               */
  223.   writeptr(0);                      /* dfh_Segment or dfh_Taglist */
  224.   writeubytes(32, thefont->name);   /* dfh_Name                   */
  225.  
  226.   /* dfh_TF.tf_Message.mn_Node: (just like dfh_DF) */
  227.  
  228.   writeubytes(10, "\0\0\0\0\0\0\0\0\x0C\0");
  229.   writeptr(fontname);
  230.  
  231.   writeptr(0);     /* dfh_TF.tf_Message.mn_Replyport */
  232.                    /*   or dfh_TF.tf_Extension       */
  233.   writeuword(0);   /* dfh_TF.tf_Message.mn_Length    */
  234.   writeuword(ys);  /* dfh_TF.tf_YSize                */
  235.  
  236.   /* dfh_TF.tf_Style: */
  237.  
  238.   writeubyte(theparams[underlined] +
  239.              2 * theparams[bold] +
  240.              4 * theparams[italic] +
  241.              8 * theparams[extended] +
  242.              64 * theparams[colorfont]);
  243.  
  244.   /* dfh_TF.tf_Flags: */
  245.  
  246.   writeubyte(66 + 4 * theparams[revpath] +
  247.              8 * theparams[talldot] +
  248.              16 * theparams[widedot] +
  249.              32 * theparams[proportional] );
  250.  
  251.   writeuword(theparams[xsize]);      /* dfh_TF.tf_XSize     */
  252.   writeuword(theparams[baseline]);   /* dfh_TF.tf_Baseline  */
  253.   writeuword(theparams[boldsmear]);  /* dfh_TF.tf_Boldsmear */
  254.   writeuword(0);                     /* dfh_TF.tf_Accessors */
  255.   writeubyte(lowchar);               /* dfh_TF.tf_LowChar   */
  256.   writeubyte(highchar);              /* dfh_TF.tf_HighChar  */
  257.   writeptr(fontdata);                /* dfh_TF.tf_CharData  */
  258.   writeword(modulo);                 /* dfh_TF.tf_Modulo    */
  259.   writeptr(fontloc);                 /* dfh_TF.tf_CharLoc   */
  260.   writeptr(fontspace);               /* dfh_TF.tf_CharSpace */
  261.   writeptr(fontkern);                /* dfh_TF.tf_CharKern  */
  262.  
  263.   if (cf) {
  264.     unsigned long cfdata, planesize = ys * modulo;
  265.     int plane;
  266.  
  267.     /* dfh_TF.ctf_Flags: */
  268.  
  269.     writeuword(thefont->usedcolors +
  270.                2 * theparams[greyfont] +
  271.                4 * theparams[antialias] );
  272.  
  273.     writeubyte(d);                      /* dfh_TF.ctf_Depth           */
  274.     writeubyte(theparams[fgcolor]);     /* dfh_TF.ctf_FgColor         */
  275.     writeubyte(theparams[low]);         /* dfh_TF.ctf_Low             */
  276.     writeubyte(theparams[high]);        /* dfh_TF.ctf_High            */
  277.     writeubyte(theparams[planepick]);   /* dfh_TF.ctf_PlanePick       */
  278.     writeubyte(theparams[planeonoff]);  /* dfh_TF.ctf_PlaneOnOff      */
  279.     writeptr(fontcolors);               /* dfh_TF.ctf_ColorFontColors */
  280.  
  281.     /* dfh_TF.ctf_CharData: */
  282.  
  283.     for (cfdata = fontdata; cfdata < fontloc; cfdata += planesize)
  284.       writeptr(cfdata);
  285.     for (plane = d; plane < 8; ++plane)
  286.       writeptr(0);
  287.   }
  288.  
  289.   /* *dfh_TF.tf_CharData: */
  290.  
  291.   for (plane = 0, bitmask = 1; plane < d; ++plane, bitmask <<= 1)
  292.     for (pmrow = pixmap, lastrow = pixmap + ys * roundedpmw;
  293.          pmrow < lastrow;
  294.          pmrow += roundedpmw)
  295.       for (pmpix = pmrow, lastpix = pmrow + roundedpmw;
  296.            pmpix < lastpix;
  297.            pmpix += 8)
  298.         writeubyte(  ((pmpix[0] & bitmask) >> plane) << 7
  299.                    | ((pmpix[1] & bitmask) >> plane) << 6
  300.                    | ((pmpix[2] & bitmask) >> plane) << 5
  301.                    | ((pmpix[3] & bitmask) >> plane) << 4
  302.                    | ((pmpix[4] & bitmask) >> plane) << 3
  303.                    | ((pmpix[5] & bitmask) >> plane) << 2
  304.                    | ((pmpix[6] & bitmask) >> plane) << 1
  305.                    | ((pmpix[7] & bitmask) >> plane) << 0
  306.                   );
  307.  
  308.   /* *dfh_TF.tf_CharLoc: */
  309.  
  310.   for (poffset = offset, pB = B, lastoffset = offset + numglyphs;
  311.        poffset < lastoffset;
  312.        ++poffset, ++pB) {
  313.     writeuword(*poffset);
  314.     writeuword(*pB);
  315.   }
  316.  
  317.   /* *dfh_TF.tf_CharSpace: */
  318.  
  319.   for (pA = A, pB = B, pC = C, lastA = A + numglyphs;
  320.        pA < lastA;
  321.        ++pA, ++pB, ++pC)
  322.     writeuword(rp ? -*pA : *pB + *pC);
  323.  
  324.   /* *dfh_TF.tf_CharKern: */
  325.  
  326.   for (pA = A, pB = B, pC = C, lastA = A + numglyphs;
  327.        pA < lastA;
  328.        ++pA, ++pB, ++pC)
  329.     writeuword(rp ? -*pB - *pC : *pA);
  330.  
  331.   if (cf) {
  332.     unsigned short *pcolor, *lastcolor;
  333.  
  334.     /* fields of *dfh_TF.ctf_ColorFontColors: */
  335.  
  336.     writeuword(0);                   /* cfc_Reserved   */
  337.     writeuword(thefont->numcolors);  /* cfc_Count      */
  338.     writeptr(colortable);            /* cfc_ColorTable */
  339.  
  340.     /* *dfh_TF.ctf_ColorFontColors->cfc_ColorTable: */
  341.  
  342.     for (pcolor = thefont->colorvals, lastcolor = pcolor + thefont->numcolors;
  343.          pcolor < lastcolor;
  344.          ++pcolor)
  345.       writeuword(*pcolor);
  346.   }
  347.  
  348.   /* pad hunk_code: */
  349.  
  350.   for (p = fontend; p < codeend; ++p) writeubyte(0);
  351.  
  352.   /* hunk_reloc32: */
  353.  
  354.   writeulong(0x3EC);
  355.   writeulong(cf ? 16 : 6);
  356.   writeulong(0);
  357.   writeubytes(24,
  358.               "\0\0\0\x0E\0\0\0\x44\0\0\0\x5C\0\0\0\x62\0\0\0\x66\0\0\0\x6A");
  359.   if (cf) {
  360.     for (p = 118; p < 154; p += 4) writeptr(p);
  361.     writeptr(fontcolors + 4);
  362.   }
  363.  
  364.   writeulong(0);
  365.  
  366.   /* hunk_end: */
  367.  
  368.   writeulong(0x3F2);
  369. }
  370.  
  371.  
  372. void usage(unsigned char **argv)  /* Prints usage message and exits. */
  373. {
  374.   warnf("usage:\n%s [-o <loadfile>] <srcfile>\n", *argv ? *argv : "bmfc");
  375.   exit(EXIT_FAILURE);
  376. }
  377.  
  378.  
  379. main(int argc, char **argv)
  380. {
  381.   const char *srcfilename = NULL, *loadfilename = NULL, **arg = argv;
  382.   char lfnspace[6];
  383.   FILE *srcfile = NULL, *loadfile = NULL;
  384.   struct font thefontspace, *thefont = &thefontspace;
  385.  
  386.   if (!*arg) usage(argv);
  387.  
  388.   for (;;) {
  389.     if (!*++arg) usage(argv);
  390.     if (**arg != '-') break;
  391.     if ((*arg)[1] != 'o' || (*arg)[2] != '\0' || !*++arg) usage(argv);
  392.     loadfilename = *arg;
  393.   }
  394.  
  395.   srcfilename = *arg;
  396.  
  397.   if (*++arg) usage(argv);
  398.  
  399.   srcfile = fopen(srcfilename, "rb");
  400.   if (!srcfile) failf(cantopenread,srcfilename);
  401.  
  402.   build(srcfile,thefont);
  403.  
  404.   if (fclose(srcfile)) warnf(cantclose,srcfilename);
  405.   srcfile = NULL;
  406.  
  407.   if (!loadfilename) {
  408.     sprintf(lfnspace, "%hu", thefont->ysize);
  409.     loadfilename = lfnspace;
  410.   }
  411.  
  412.   loadfile = fopen(loadfilename, "wb");
  413.   if (!loadfile) failf(cantopenwrite,loadfilename);
  414.  
  415.   writeloadfile(loadfile,thefont);
  416.  
  417.   if (fclose(loadfile)) warnf(cantclose,loadfilename);
  418.   loadfile = NULL;
  419.  
  420.   warnf(success);
  421.   warnf(outputto,loadfilename);
  422.   exit(EXIT_SUCCESS);
  423. }
  424.